package com.example.redis.controller;

import com.example.redis.entity.TestDemo;
import com.example.redis.service.RedisDistributedLockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author xianxin
 * @since 2020/8/22
 */
@RestController
public class RedisDistributedLockController {

    @Autowired
    private RedisDistributedLockService redisDistributedLockService;

    @RequestMapping(path = "save")
    public String simulationConcurrent() {
        StopWatch watch = new StopWatch();
        watch.start();

        int nThreads = 20;

        ExecutorService exec = Executors.newFixedThreadPool(nThreads);

        for (int i = 0; i < nThreads; i++) {
            exec.execute(() -> {
                TestDemo demo = new TestDemo();
                demo.setCity("310100");
                demo.setName("张三");
                demo.setAge(22);
                redisDistributedLockService.insert(demo);
            });
        }
        watch.stop();
        double time = watch.getTotalTimeSeconds();

        // 验证结果：【加锁】name+city来控制唯一key，在多线程并发的情况下最终入库一条数据
        return "操作完成,耗时:" + time + "s";
    }

    @RequestMapping(path = "save2")
    public String simulationConcurrent2() {
        StopWatch watch = new StopWatch();
        watch.start();

        int nThreads = 20;

        ExecutorService exec = Executors.newFixedThreadPool(nThreads);

        for (int i = 0; i < nThreads; i++) {
            exec.execute(() -> {
                TestDemo demo = new TestDemo();
                demo.setCity("310100");
                demo.setName("李四");
                demo.setAge(23);
                redisDistributedLockService.insert2(demo);
            });
        }
        watch.stop();
        double time = watch.getTotalTimeSeconds();

        // 验证结果：【未加锁】name+city来控制唯一key，在多线程并发的情况下最终几乎所有线程的数据都入库了
        return "操作完成,耗时:" + time + "s";
    }
}
